#ifndef COCOSVIEWLIST_H_20111124
#define COCOSVIEWLIST_H_20111124

#include "cocos2d.h"
#include "CocosMarcos.h"
#include "CocosDialog.h"
#include "GameDefines.h"
#include <vector>
#include <cmath>

using namespace cocos2d;

class CCocosViewList : public cocos2d::CCSprite, public cocos2d::CCStandardTouchDelegate
{
public:
	void onEnter()
	{
		cocos2d::CCSprite::onEnter();
		cocos2d::CCTouchDispatcher::sharedDispatcher()->addStandardDelegate(this,0);
	}

	void onExit()
	{
		cocos2d::CCTouchDispatcher::sharedDispatcher()->removeDelegate(this);
		cocos2d::CCSprite::onExit();
	}

	bool containsTouchLocation(cocos2d::CCTouch *pTouch)
	{
		cocos2d::CCSize s = getContentSize(); 

		return (CCRect::CCRectContainsPoint(CCRectMake(-s.width / 2, -s.height / 2, s.width, s.height),convertTouchToNodeSpaceAR(pTouch)));
	}

	bool containsTouchLocation(cocos2d::CCTouch *pTouch, cocos2d::CCRect rc)
	{
		return (CCRect::CCRectContainsPoint(rc,convertTouchToNodeSpaceAR(pTouch)));
	}

public:
	static CCocosViewList* spriteWithTexture(cocos2d::CCTexture2D *pTexture)
	{
		CCocosViewList *pobSprite = new CCocosViewList();
		pobSprite->initWithTexture(pTexture);
		pobSprite->autorelease();

		return pobSprite;
	}

	static CCocosViewList* spriteWithTexture(cocos2d::CCTexture2D *pTexture, cocos2d::CCRect rect)
	{
		CCocosViewList *pobSprite = new CCocosViewList();
		pobSprite->initWithTexture(pTexture, rect);
		pobSprite->autorelease();

		return pobSprite;
	}


	static CCocosViewList* spriteWithFile(const char *pszFileName)
	{
		CCocosViewList *pobSprite = new CCocosViewList();
		pobSprite->initWithFile(pszFileName);
		pobSprite->autorelease();

		return pobSprite;
	}

	static CCocosViewList* spriteWithFile(const char *pszFileName, cocos2d::CCRect rect)
	{
		CCocosViewList *pobSprite = new CCocosViewList();
		pobSprite->initWithFile(pszFileName, rect);
		pobSprite->autorelease();

		return pobSprite;
	}

	static CSpriteButton* spriteWithSpriteFrame(cocos2d::CCSpriteFrame *pSpriteFrame)
	{
		CSpriteButton *pobSprite = new CSpriteButton();
		pobSprite->initWithSpriteFrame(pSpriteFrame);
		pobSprite->autorelease();

		return pobSprite;
	}

	static CSpriteButton* spriteWithSpriteFrameName(const char *pszSpriteFrameName)
	{
		cocos2d::CCSpriteFrame *pFrame = cocos2d::CCSpriteFrameCache::sharedSpriteFrameCache()->spriteFrameByName(pszSpriteFrameName);
		return spriteWithSpriteFrame(pFrame);
	}

public:
	virtual void ccTouchesBegan(cocos2d::CCSet *pTouches, cocos2d::CCEvent *pEvent) 
	{
		if(!m_bEnable)
		{
			return;
		}
		if(!pTouches||!pTouches->count())
			return;
		cocos2d::CCTouch* pTouch = (cocos2d::CCTouch*)(*(pTouches->begin()));
		if(containsTouchLocation(pTouch))
		{
			if(containsTouchLocation(pTouch, m_rcTouch))
			{
				m_bTouched = true;
				m_ptLast = pTouch->locationInView(pTouch->view());
				m_bAutoMoving = false;
				m_bCalSpeeding = true;
			}
			
		}
	}

	virtual void ccTouchesMoved(cocos2d::CCSet *pTouches, cocos2d::CCEvent *pEvent) 
	{
		if(!m_bEnable)
		{
			return;
		}
		if(!pTouches||!pTouches->count())
			return;
		cocos2d::CCTouch* pTouch = (cocos2d::CCTouch*)(*(pTouches->begin()));
		if(containsTouchLocation(pTouch))
		{
			if(m_bTouched)
			{
				CCPoint ptCur = pTouch->locationInView(pTouch->view());
				float yDiff = ptCur.y - m_ptLast.y;
#if (CC_TARGET_PLATFORM == CC_PLATFORM_IOS)
                yDiff = m_ptLast.x - ptCur.x;
#endif
				if(m_rcTouch.size.height > m_itemHeightCount)
				{
					yDiff *= 0.5f;
				}
				else if((m_topY > m_itemHeightCount + m_ptViewList.y - m_rcTouch.size.height && yDiff < 0)|| 
					(m_topY < m_ptViewList.y && yDiff > 0))
				{
					yDiff *= 0.5f;
				}
				m_curSpeed = -yDiff;
				m_bCalSpeeding = true;
				m_topY -= yDiff;
				m_ptLast = ptCur;
			}
		}
	}

	virtual void ccTouchesEnded(cocos2d::CCSet *pTouches, cocos2d::CCEvent *pEvent) 
	{
		if(!m_bEnable)
		{
			return;
		}
		if(!pTouches||!pTouches->count())
			return;
		cocos2d::CCTouch* pTouch = (cocos2d::CCTouch*)(*(pTouches->begin()));
	
		if(containsTouchLocation(pTouch))
		{
		
		}	

		m_bCalSpeeding = false;
		m_bTouched = false;
	}

	virtual void ccTouchesCancelled(cocos2d::CCSet *pTouches, cocos2d::CCEvent *pEvent) 
	{
		m_bTouched = false;
		m_bCalSpeeding = false;

	}

	LAYER_NODE_FUNC(CCocosViewList);

public:
	CCocosViewList()
		: m_bEnable(false)
		, m_bTouched(false)
		, m_diffY(0)
		, m_topY(0)
		, m_rowSpace(10)
		, m_itemHeightCount(0)
		, m_curSpeed(0)
		, m_pLayList(NULL)
		, m_bAutoMoving(false)
	{

	}
	~CCocosViewList()
	{

	}

	CCNode *GetListLayer()         {return m_pLayList;}
	void SetIsEnable(bool bEnable) 
	{
		m_bEnable = bEnable;

		for(vector<CCocosDialog *>::iterator iter = m_vItems.begin(); iter != m_vItems.end(); iter++)
		{
			(*iter)->EnableButtons(bEnable);
		}
	}

	bool Create(cocos2d::CCRect rcClickable, CButtonListener *pBtnListener)
	{
		CCSize s = CCDirector::sharedDirector()->getWinSize();
		//m_rcTouch.origin = ccp(rcClickable.origin.x + getPosition().x - getContentSize().width*0.5f,
		//					  s.height - (rcClickable.origin.y + getPosition().y - getContentSize().height*0.5f + rcClickable.size.height));
		m_rcTouch.origin = ccp(rcClickable.origin.x - s.width*0.5f, rcClickable.origin.y - s.height*0.5f);
		m_rcTouch.size = rcClickable.size;
		m_bEnable = true;
		m_pLayList = CCLayer::node();
		m_ptViewList = ccp(rcClickable.origin.x + rcClickable.size.width*0.5f, rcClickable.origin.y + rcClickable.size.height*0.5f);
		m_pLayList->setPosition(m_ptViewList);

		m_topY = m_ptViewList.y;

		addChild(m_pLayList);

		return true;
	}

	void AddItem(CCocosDialog *pNewItem)
	{
		m_vItems.push_back(pNewItem);
		m_itemHeightCount += (pNewItem->GetHeight() + m_rowSpace);

	}

	void ResortItems()
	{
		m_bAutoMoving = false;
		m_topY = m_ptViewList.y;
	}

	void BeginUpdate()
	{
		float heightAdd = 0;
		if(m_vItems.size() != 0)
		{
			heightAdd =(*m_vItems.begin())->GetHeight()*0.5f;
		}

		for(vector<CCocosDialog *>::iterator iter = m_vItems.begin(); iter != m_vItems.end(); iter++)
		{	
			CCocosDialog *pCurDlg = *iter;
			pCurDlg->SetPosition(ccp(0, m_rcTouch.size.height*0.5f - heightAdd));

			if(!m_bEnable)
			{
				pCurDlg->Pop(CCocosDialog::POP_NONE);
			}
			else
			{
				pCurDlg->Pop(CCocosDialog::POP_SIMPLE);
			}

			heightAdd = heightAdd + pCurDlg->GetHeight() + m_rowSpace;
		}
		schedule(schedule_selector(CCocosViewList::OnUpdate));
	}

	void StopUpdate()
	{
		unscheduleAllSelectors();
	}

	void OnUpdate(cocos2d::ccTime dt)
	{
		

		if(!m_bCalSpeeding)
		{
			if(m_bAutoMoving)
			{
				if(m_rcTouch.size.height > m_itemHeightCount)
				{	
					if(abs(m_topY - m_ptViewList.y) < abs(m_curSpeed))
					{
						m_bAutoMoving = false;
						m_topY = m_ptViewList.y;
						m_curSpeed = 0;
					}
				}
				else if((m_topY+m_curSpeed) >= m_ptViewList.y && (m_topY + m_curSpeed)<= m_itemHeightCount + m_ptViewList.y - m_rcTouch.size.height)
				{
					m_bAutoMoving = false;

					if(m_curSpeed > 0)
					{
						m_topY = m_ptViewList.y;
					}
					else
					{
						m_topY = m_itemHeightCount + m_ptViewList.y - m_rcTouch.size.height;
					}

					m_curSpeed = 0;
				}
			}
			else
			{
				if(m_curSpeed > 0)
				{
					m_curSpeed -= 1;
				}
				else if(m_curSpeed < 0)
				{
					m_curSpeed += 1;
				}

				if(abs(m_curSpeed) < 1)
				{
					m_curSpeed = 0;
				}

				if(m_rcTouch.size.height > m_itemHeightCount)
				{
					m_curSpeed = ( m_ptViewList.y - m_topY) / 30.0f;
					m_bAutoMoving = true;
				}
				else
				{
					if(m_topY > m_itemHeightCount + m_ptViewList.y - m_rcTouch.size.height)
					{
						m_curSpeed = ((m_itemHeightCount + m_ptViewList.y - m_rcTouch.size.height) - m_topY) / 30.0f;
						m_bAutoMoving = true;
					}
					else if(m_topY < m_ptViewList.y)
					{
						m_curSpeed = ( m_ptViewList.y - m_topY) / 30.0f;
						m_bAutoMoving = true;
					}
				}		
			}
			

			m_topY += m_curSpeed;
		}

		m_pLayList->setPosition(ccp(m_ptViewList.x, m_topY));

		for(vector<CCocosDialog *>::iterator iter = m_vItems.begin(); iter != m_vItems.end(); iter++)
		{	
			CCocosDialog *pCurDlg = *iter;
			cocos2d::CCPoint pt = pCurDlg->GetPosition();
			if(pt.y + m_topY > m_ptViewList.y + m_rcTouch.size.height*0.5f + pCurDlg->GetHeight()*0.5f||
			   m_topY + pt.y < m_ptViewList.y - m_rcTouch.size.height*0.5f - pCurDlg->GetHeight()*0.5f)
			{

				pCurDlg->Shut(CCocosDialog::SHUT_NONE);
			}
			else
			{	
				if(!m_bEnable)
				{
					pCurDlg->Pop(CCocosDialog::POP_NONE);
				}
				else
				{
					pCurDlg->Pop(CCocosDialog::POP_SIMPLE);
				}
			}
		}

	}
private:
	bool                    m_bEnable;
	int				        m_zOrder;
	vector<CCocosDialog *>  m_vItems;
	
	cocos2d::CCRect  m_rcTouch;
	cocos2d::CCPoint m_ptLast;
	cocos2d::CCPoint m_ptViewList;
	cocos2d::CCLayer *m_pLayList;

	bool             m_bTouched;
	bool             m_bAutoMoving;
	bool             m_bCalSpeeding;
	
	float            m_diffY;
	float            m_topY;
	float            m_curSpeed;
	float            m_rowSpace;
	float            m_itemHeightCount;
	
	
};

#endif